﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using SedionFormDesigner.Infrastructure;
using System.Diagnostics;
using System.Collections;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing.Design;
using SedionFormDesigner.Service;
using System.Xml.Linq;
using SedionFormDesigner.Serializer;

namespace SedionFormDesigner.Designer
{
    public partial class SedionDesignerHost
    {
        private Int32 hostIndex = 1;
        private DesignerLoader designerLoader;
        // 名称->designSite的映射
        private Hashtable sites;
        // 组件<->designer之间的映射
        private Hashtable designerTable;
        // 基础的文件组件
        private IComponent rootComponent;
        // 基础组件的类名
        private String rootComponentClassName;
        // 用于显示的类
        private SedionDocumentWindow documentWindow;
        // selection service
        private ISelectionService selectionService;
        // toolbox service
        private IToolboxService toolboxService;
        // menu command service
        private IMenuCommandService menuCommandService;

        // 持有添加的全局服务
        private IServiceContainer serviceContainer;

        public SedionDesignerHost(IServiceProvider parentProvider, Int32 hostIndex)
        {
            this.hostIndex = hostIndex;

            this.serviceContainer = new ServiceContainer(parentProvider);
            designerTable = new Hashtable();
            sites = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
            loadingDesigner = false;
            transactionCount = 0;
            reloading = false;

            // 添加已经支持的服务
            serviceContainer.AddService(typeof(IDesignerHost), this);
            serviceContainer.AddService(typeof(IContainer), this);
            serviceContainer.AddService(typeof(IComponentChangeService), this);
            serviceContainer.AddService(typeof(IExtenderProviderService), this);
            serviceContainer.AddService(typeof(IDesignerEventService), this);

            // 需要实现的服务
            ServiceCreatorCallback callback = new ServiceCreatorCallback(this.OnCreateService);

            serviceContainer.AddService(typeof(IToolboxService), callback);
            serviceContainer.AddService(typeof(ISelectionService), callback);
            serviceContainer.AddService(typeof(ITypeDescriptorFilterService), callback);
            serviceContainer.AddService(typeof(IMenuCommandService), callback);

            ((IExtenderProviderService)this).AddExtenderProvider(new SedionNameExtenderProvider(this));
            ((IExtenderProviderService)this).AddExtenderProvider(new SedionInheriteNameExtendProvider(this));
        }

        public XElement Save(Int32 index)
        {
            var form = getForm(View);
            return FormSerializer.SerializeControlToXml(form, index);
        }

        private Control getForm(Control parentCtrl)
        {
            if (parentCtrl.GetType() == typeof(System.Windows.Forms.Form))
                return parentCtrl;
            else
            {
                Control result = parentCtrl;
                if (parentCtrl.Controls.Count > 0)
                {
                    foreach (Control ctrl in parentCtrl.Controls)
                    {
                        result = getForm(ctrl);
                    }
                }
                return result;
            }
        }

        /// <summary>
        ///  创建更多的服务
        /// </summary>
        private Object OnCreateService(IServiceContainer container, Type serviceType)
        {
            if (serviceType == typeof(ISelectionService))
            {
                if (selectionService == null)
                    selectionService = new SedionSelectionService(this);
                return selectionService;
            }
            else if (serviceType == typeof(ITypeDescriptorFilterService))
            {
                return new SedionTypeDescriptorFilterService(this);
            }
            else if (serviceType == typeof(IToolboxService))
            {
                if (toolboxService == null)
                    toolboxService = new SedionToolboxService(this);
                return toolboxService;
            }
            else if (serviceType == typeof(IMenuCommandService))
            {
                if (menuCommandService == null)
                    menuCommandService = new SedionMenuCommandService(this);
                return menuCommandService;
            }

            Debug.Fail(String.Concat("Service type ", serviceType.FullName, " requested but we don't support it."));
            return null;
        }

        /// <summary>
        ///  导入设计器的容器
        /// </summary>
        public void LoadDocument(DesignerLoader designerLoader)
        {
            try
            {
                this.designerLoader = designerLoader;

                documentWindow = new SedionDocumentWindow(this);
                Load(false);
            }
            catch (Exception ex)
            {
                Debug.Fail(ex.ToString());
                throw;
            }
        }

        /// <summary>
        ///  返回设计器控件
        /// </summary>
        public Control View
        {
            get
            {
                return documentWindow;
            }
        }

        public void Dispose()
        {
            if (designerLoader != null)
            {
                try
                {
                    designerLoader.Dispose();
                }
                catch (Exception ex)
                {
                    Debug.Fail(String.Concat("Designer loader '", designerLoader.GetType().Name, "' threw during Dispose: ", ex.ToString()));
                    ex = null;
                }
                designerLoader = null;
            }

            UnloadDocument();

            serviceContainer = null;

            if (menuCommandService != null)
            {
                IDisposable dispose = menuCommandService as IDisposable;
                if (dispose != null) dispose.Dispose();
                menuCommandService = null;
            }

            if (selectionService != null)
            {
                IDisposable dispose = selectionService as IDisposable;
                if (dispose != null) dispose.Dispose();
                selectionService = null;
            }

            if (menuCommandService != null)
            {
                IDisposable dispose = menuCommandService as IDisposable;
                if (dispose != null) dispose.Dispose();
                menuCommandService = null;
            }

            if (toolboxService != null)
            {
                IDisposable dispose = toolboxService as IDisposable;
                if (dispose != null) dispose.Dispose();
                toolboxService = null;
            }

            if (documentWindow != null)
            {
                documentWindow.Dispose();
                documentWindow = null;
            }
        }
    }

    /// <summary>
    ///  实现管理设计器事务和组件
    /// </summary>
    public partial class SedionDesignerHost : IDesignerHost
    {
        // 记录事务的个数
        private Int32 transactionCount;
        // 当前事务的文字描述
        internal StringStack transactionDescriptions;
        // 通过这个对象导入类型
        private ITypeResolutionService typeResolver;

        private SedionDesignSite newComponentSite;

        /// <summary>
        ///  获得名称->designSite的映射集合
        /// </summary>
        internal Hashtable Sites
        {
            get
            {
                return sites;
            }
        }

        /// <summary>
        ///  获得/设置事务的数量
        /// </summary>
        internal Int32 TransactionCount
        {
            get
            {
                return transactionCount;
            }
            set
            {
                transactionCount = value;
            }
        }

        /// <summary>
        ///  获得所有事务的文字描述
        /// </summary>
        internal StringStack TransactionDescriptions
        {
            get
            {
                if (transactionDescriptions == null)
                    transactionDescriptions = new StringStack();
                return transactionDescriptions;
            }
        }

        /// <summary>
        ///  移除组件
        /// </summary>
        private void Remove(IComponent component)
        {
            // 如果组件没有添加到集合当中
            if (component == null) return;
            ISite site = component.Site;
            if (!sites.ContainsValue(site)) return;
            if (site == null || site.Container != this) return;
            if (!(site is SedionDesignSite)) return;

            ComponentEventArgs come = new ComponentEventArgs(component);
            OnComponentRemoving(come);

            // 如果是扩展组件,那么从扩展队列中删除扩展组件
            SedionDesignSite ssite = (SedionDesignSite)site;
            if (ssite.Component != rootComponent)
            {
                if (component is IExtenderProvider)
                    ((IExtenderProviderService)this).RemoveExtenderProvider((IExtenderProvider)component);
            }

            // 并且移除对应的设计器
            IDesigner designer = (IDesigner)designerTable[component];
            if (designer != null)
                designer.Dispose();

            designerTable.Remove(component);

            sites.Remove(ssite.Name);
            if (components != null)
                components.Remove(site);

            try
            {
                OnComponentRemoved(come);
            }
            catch (Exception) { }

            component.Site = null;
        }

        /// <summary>
        ///  给予新组件的类型创建一个名称
        /// </summary>
        internal String GetNewComponentName(Type compClass)
        {
            IServiceProvider provider = (IServiceProvider)this;
            INameCreationService nameCreate = (INameCreationService)provider.GetService(typeof(INameCreationService));
            if (nameCreate != null)
                return nameCreate.CreateName(Container, compClass);

            String baseName = String.Concat(compClass.Name, hostIndex);

            Int32 index = 1;
            String finalName = String.Concat(baseName, index.ToString());
            while (Container.Components[finalName] != null)
            {
                index++;
                finalName = String.Concat(baseName, index.ToString());
            }

            return finalName;
        }

        /// <summary>
        ///  创建对象,并给定参数和类型
        /// </summary>
        private Object CreateObject(Type objectClass, Object[] args, Type[] argTypes, Boolean fThrowException)
        {
            ConstructorInfo ctr = null;

            if (args != null && args.Length > 0)
            {
                if (argTypes == null)
                {
                    argTypes = new Type[args.Length];

                    for (int i = args.Length - 1; i >= 0; i--)
                    {
                        if (args[i] != null) argTypes[i] = args[i].GetType();
                    }
                }

                // 获得构造函数的相关信息
                ctr = objectClass.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, argTypes, null);

                if (ctr == null && fThrowException)
                    throw new Exception(String.Concat("Cannot find a constructor with the right argument for ", objectClass.FullName));
                else
                    return null;
            }

            try
            {
                // 如果构造函数创建失败,那么直接创建实例否则传入参数执行
                return (ctr == null) ? Activator.CreateInstance(objectClass) : ctr.Invoke(args);
            }
            catch (Exception e)
            {
                if (e is TargetInvocationException)
                    e = e.InnerException;

                String message = e.Message;
                if (message == null)
                    message = e.ToString();

                throw new Exception(String.Concat("Cannot create an instance of ", objectClass.FullName, " because ", e.ToString()), e);
            }
        }

        #region IDesignerHost 成员

        public event EventHandler Activated;
        public event EventHandler Deactivated;
        public event EventHandler LoadComplete;

        public event DesignerTransactionCloseEventHandler TransactionClosed;
        internal void OnTransactionClosed(DesignerTransactionCloseEventArgs e)
        {
            if (TransactionClosed != null)
                TransactionClosed(this, e);
        }

        public event DesignerTransactionCloseEventHandler TransactionClosing;
        internal void OnTransactionClosing(DesignerTransactionCloseEventArgs e)
        {
            if (TransactionClosing != null)
                TransactionClosing(this, e);
        }

        public event EventHandler TransactionOpened;
        internal void OnTransactionOpened(EventArgs e)
        {
            if (TransactionOpened != null)
                TransactionOpened(this, e);
        }

        public event EventHandler TransactionOpening;
        internal void OnTransactionOpening(EventArgs e)
        {
            if (TransactionOpening != null)
                TransactionOpening(this, e);
        }

        public void Activate()
        {
            documentWindow.Focus();
        }

        public IContainer Container
        {
            get { return (IContainer)this; }
        }

        public IComponent CreateComponent(Type componentClass, string name)
        {
            Object obj = null;
            IComponent comp = null;
            newComponentSite = new SedionDesignSite(this, name);
            try
            {
                // IContainer结构创建组件
                try
                {
                    Object[] args = new Object[] { this };
                    Type[] argTypes = new Type[] { typeof(IContainer) };
                    obj = CreateObject(componentClass, args, argTypes, false);
                }
                catch (Exception) { }

                // 失败的话用默认结构创建组件
                if (obj == null)
                    obj = CreateObject(componentClass, null, null, false);

                // 确保成功创建组件
                comp = obj as Component;
                if (comp == null)
                    throw new Exception(String.Concat("The class is not a component ", componentClass.FullName));

                // 如果创建的组件的Site不是SedionDesignSite
                // 那么调用Container.Add方法添加组件到组件集合中
                SedionDesignSite site = comp.Site as SedionDesignSite;
                if (site == null)
                    ((IContainer)this).Add(comp);

                Debug.Assert(newComponentSite == null, "add didn't use newComponentSite.");
            }
            catch (Exception)
            {
                if (comp != null)
                {
                    try
                    {
                        DestroyComponent(comp);
                    }
                    catch (Exception) { }
                }
                throw;
            }
            return comp;
        }

        public IComponent CreateComponent(Type componentClass)
        {
            String name = this.GetNewComponentName(componentClass);
            return CreateComponent(componentClass, name);
        }

        public DesignerTransaction CreateTransaction(string description)
        {
            if (description == null)
                description = String.Empty;
            return new SedionDesignerTransaction(this, description);
        }

        public DesignerTransaction CreateTransaction()
        {
            return CreateTransaction(null);
        }

        /// <summary>
        ///  销毁组件,并从design container中移除
        /// </summary>
        public void DestroyComponent(IComponent component)
        {
            String name;
            if (component.Site != null && component.Site.Name != null)
                name = component.Site.Name;
            else
                name = component.GetType().Name;

            // 确保组件没有被继承,否则无法删除
            InheritanceAttribute inheAttr = (InheritanceAttribute)TypeDescriptor.GetAttributes(component)[typeof(InheritanceAttribute)];
            if (inheAttr != null && inheAttr.InheritanceLevel != InheritanceLevel.NotInherited)
                throw new InvalidOperationException(String.Concat("CantDestroyInheritedComponent ", name));

            DesignerTransaction trans = null;
            try
            {
                // 创建事务,在删除组件之前先移除它
                trans = CreateTransaction(String.Concat("DesctroyComponentTransaction ", name));

                // 需要主动调用删除事件,而不是在Dispose中删除
                // 防止发生删除已经不存在的组件的事件
                ((IComponentChangeService)this).OnComponentChanging(component, null);
                if (component.Site != null)
                    Remove(component);
                component.Dispose();
                ((IComponentChangeService)this).OnComponentChanged(component, null, null, null);
            }
            finally
            {
                if (trans != null)
                    trans.Commit();
            }
        }

        /// <summary>
        ///  根据组件获得设计器
        /// </summary>
        public IDesigner GetDesigner(IComponent component)
        {
            Debug.Assert(component != null, "Cannot call GetDesigner with a NULL component. Check that the root hasn't been disposed.");
            if (component == null) throw new ArgumentNullException("component");
            return (IDesigner)designerTable[component];
        }

        /// <summary>
        ///   根据类型名获得类型对象
        /// </summary>
        public Type GetType(string typeName)
        {
            if (typeResolver == null)
            {
                IServiceProvider provider = (IServiceProvider)this;
                typeResolver = (ITypeResolutionService)provider.GetService(typeof(ITypeResolutionService));
            }

            if (typeResolver != null)
                return typeResolver.GetType(typeName);

            return Type.GetType(typeName);
        }

        /// <summary>
        ///  在执行事务返回true
        /// </summary>
        public bool InTransaction
        {
            get { return transactionCount > 0; }
        }

        /// <summary>
        ///  是否在加载中...
        /// </summary>
        public bool Loading
        {
            get { return loadingDesigner || (designerLoader != null && designerLoader.Loading); }
        }

        /// <summary>
        ///  获得设计器中充当基础组件的对象
        ///  一般是Form或者UserControl
        /// </summary>
        public IComponent RootComponent
        {
            get { return rootComponent; }
        }

        /// <summary>
        ///  获得基础组件的完整类型名
        /// </summary>
        public string RootComponentClassName
        {
            get { return rootComponentClassName; }
        }

        public string TransactionDescription
        {
            get
            {
                if (transactionDescriptions != null) { return transactionDescriptions.GetNonNull(); }
                return String.Empty;
            }
        }

        #endregion

        #region IServiceContainer 成员

        public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote)
        {
            Debug.Assert(serviceContainer != null, "We have no sevice container.  Either the host has not been initialized yet or it has been disposed.");
            if (serviceContainer != null)
                serviceContainer.AddService(serviceType, callback, promote);
        }

        public void AddService(Type serviceType, ServiceCreatorCallback callback)
        {
            Debug.Assert(serviceContainer != null, "We have no service container. Either the host has not been initialized yet or it has been disposed.");
            if (serviceContainer != null)
                serviceContainer.AddService(serviceType, callback);
        }

        public void AddService(Type serviceType, object serviceInstance, bool promote)
        {
            Debug.Assert(serviceContainer != null, "We have no sevice container.  Either the host has not been initialized yet or it has been disposed.");
            if (serviceContainer != null)
                serviceContainer.AddService(serviceType, serviceInstance, promote);
        }

        public void AddService(Type serviceType, object serviceInstance)
        {
            Debug.Assert(serviceContainer != null, "We have no sevice container.  Either the host has not been initialized yet or it has been disposed.");
            if (serviceContainer != null)
                serviceContainer.AddService(serviceType, serviceInstance);
        }

        public void RemoveService(Type serviceType, bool promote)
        {
            if (serviceContainer != null)
                serviceContainer.RemoveService(serviceType, promote);
        }

        public void RemoveService(Type serviceType)
        {
            if (serviceContainer != null)
                serviceContainer.RemoveService(serviceType);
        }

        #endregion

        #region IServiceProvider 成员

        public object GetService(Type serviceType)
        {
            Debug.Assert(serviceContainer != null, "We have no service container. Either the host has not been initialized yet or it has been disposed.");
            Object service = null;
            if (serviceContainer != null)
            {
                service = serviceContainer.GetService(serviceType);
                ServiceRequests requets = (ServiceRequests)serviceContainer.GetService(typeof(ServiceRequests));
                if (requets != null)
                {
                    if (service != null)
                        requets.ServiceSucceeded(serviceType);
                    else
                        requets.ServiceFailed(serviceType);
                }
            }
            return service;
        }

        #endregion
    }

    /// <summary>
    ///  实现提供容器功能
    /// </summary>
    public partial class SedionDesignerHost : IContainer
    {
        // 组件的集合,用来追踪site
        private DesignerComponentCollection components;
        // 用来验证名称的服务
        private INameCreationService nameService;
        // 对文件处理的设计器
        private IRootDesigner rootDesigner;


        /// <summary>
        ///  验证名称合法,而且名称不重复
        /// </summary>
        internal void CheckName(String name)
        {
            if (name == null || name.Length == 0)
                throw new Exception("Components must have a name.");

            if (((IContainer)this).Components[name] != null)
                throw new Exception(String.Concat("We already have a component named ", name));

            if (nameService == null)
            {
                IServiceProvider provider = (IServiceProvider)this;
                nameService = (INameCreationService)provider.GetService(typeof(INameCreationService));
            }

            if (nameService != null)
                nameService.ValidateName(name);
        }

        /// <summary>
        ///  创建组件设计器
        /// </summary>
        private void CreateComponentDesigner(IComponent component)
        {
            IDesigner designer = null;

            // 如果是创建第一个组件那么必须是底层的组件
            if (rootComponent == null)
            {
                rootComponent = component;

                // 获得底层设计器,检查是否支持这种设计器
                rootDesigner = (IRootDesigner)TypeDescriptor.CreateDesigner(component, typeof(IRootDesigner));

                if (rootDesigner == null)
                {
                    rootComponent = null;
                    throw new Exception(String.Concat("No Top Level Designer for ", component.GetType().FullName));
                }

                ViewTechnology[] technologies = rootDesigner.SupportedTechnologies;
                Boolean supported = false;
                foreach (ViewTechnology tech in technologies)
                {
                    if (tech == ViewTechnology.Default)
                    {
                        supported = true;
                        break;
                    }
                }

                if (!supported)
                    throw new Exception(String.Concat("This designer host does not support the designer for ", component.GetType().FullName));

                designer = rootDesigner;

                // 检查底层类名是否被设置
                if (rootComponentClassName == null)
                    rootComponentClassName = component.Site.Name;
            }
            else
            {
                designer = TypeDescriptor.CreateDesigner(component, typeof(IDesigner));
            }

            if (designer != null)
            {
                designerTable[component] = designer;

                try
                {
                    designer.Initialize(component);
                }
                catch
                {
                    designerTable.Remove(component);

                    if (designer == rootDesigner)
                        rootDesigner = null;
                    throw;
                }

                // 如果是扩展组件,那么添加到扩展组件集合中
                if (designer is IExtenderProvider &&
                    !TypeDescriptor.GetAttributes(designer).Contains(InheritanceAttribute.InheritedReadOnly))
                {
                    ((IExtenderProviderService)this).AddExtenderProvider((IExtenderProvider)designer);
                }

                // 如果是底层组件,那么初始化添加窗体
                if (designer == rootDesigner)
                    documentWindow.SetDesigner(rootDesigner);
            }
        }



        #region IContainer 成员

        void IContainer.Add(IComponent component, string name)
        {
            if (component == null) return;

            if (rootComponent != null)
            {
                // 将组件和根组件类名比较
                // 如果相同抛出异常,不能添加自己
                if (String.Compare(component.GetType().FullName, rootComponentClassName, true) == 0)
                    throw new Exception(String.Concat("Can't add a component to itself", component.GetType().FullName));
            }

            ISite site = component.Site;

            // 如果组件已经添加,那么检查名称不同的话重命名!
            if (site != null && site.Container == this)
            {
                if (name != null && !name.Equals(site.Name))
                {
                    CheckName(name);
                    site.Name = name;
                }
                return;
            }

            // 检查是否已经存在site,没有的话创建一个
            SedionDesignSite newSite = newComponentSite;
            newComponentSite = null;

            if (newSite != null && name == null)
                name = newSite.Name;

            // 确保名称有效
            if (name != null)
                CheckName(name);


            ComponentEventArgs ce = new ComponentEventArgs(component);
            OnComponentAdding(ce);

            // 从当前的site中移除组件
            if (site != null) site.Container.Remove(component);
            if (newSite == null)
                newSite = new SedionDesignSite(this, name);

            // 为site设置component并赋予名称
            newSite.SetComponent(component);

            Debug.Assert(name == null || name.Equals(newSite.Name), "Name should match the one in newComponentSite");
            if (component is IExtenderProvider &&
                !TypeDescriptor.GetAttributes(component).Contains(InheritanceAttribute.InheritedReadOnly))
            {
                ((IExtenderProviderService)this).AddExtenderProvider((IExtenderProvider)component);
            }

            // 建立component/site键值对
            sites[newSite.Name] = newSite;
            component.Site = newSite;
            if (component != null)
                components.Add(newSite);

            try
            {
                CreateComponentDesigner(component);

                // component已经添加了,发出通知
                OnComponentAdded(ce);
            }
            catch (Exception)
            {
                // 如果在载入过程中,那么取消移除
                if (!loadingDesigner)
                    ((IContainer)this).Remove(component);
                throw;
            }
        }

        void IContainer.Add(IComponent component)
        {
            ((IContainer)this).Add(component, null);
        }

        /// <summary>
        ///  获得组件集合
        /// </summary>
        ComponentCollection IContainer.Components
        {
            get
            {
                if (components == null)
                    components = new DesignerComponentCollection(this);
                return components;
            }
        }

        void IContainer.Remove(IComponent component)
        {
            if (component == null) return;
            ISite site = component.Site;
            if (!sites.ContainsValue(site)) return;
            if (site == null || site.Container != this) return;
            if (!(site is SedionDesignSite)) return;

            ComponentEventArgs ce = new ComponentEventArgs(component);
            OnComponentRemoving(ce);

            SedionDesignSite csite = (SedionDesignSite)site;
            if (csite.Component != rootComponent)
            {
                if (component is IExtenderProvider)
                    ((IExtenderProviderService)this).RemoveExtenderProvider((IExtenderProvider)component);
            }

            // 在缓存的集合中移除该移除的
            IDesigner designer = (IDesigner)designerTable[component];
            if (designer != null)
                designer.Dispose();

            designerTable.Remove(component);

            sites.Remove(csite.Name);
            if (components != null)
                components.Remove(site);

            try
            {
                OnComponentRemoved(ce);
            }
            catch (Exception) { }

            component.Site = null;

        }

        #endregion

        #region IDisposable 成员

        void IDisposable.Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    /// <summary>
    ///  实现宿主以序列化形式加载
    /// </summary>
    public partial class SedionDesignerHost : IDesignerLoaderHost
    {
        // 正在加载则返回true;
        private Boolean loadingDesigner;
        // 是否重新导入文件(document)
        private Boolean reloading;
        // 第一次导入错误,或者为null
        private Exception loadError;

        /// <summary>
        ///  在加载和重新加载时卸载当前设计器
        /// </summary>
        private void UnloadDocument()
        {
            // 能获得selection服务,那么清除它
            // 防止选择器记录已经销毁的组件或者设计器
            IServiceProvider serviceProvider = (IServiceProvider)this;
            ISelectionService selectionService = (ISelectionService)serviceProvider.GetService(typeof(ISelectionService));
            Debug.Assert(selectionService != null, "ISelectionService not found");
            if (selectionService != null)
                selectionService.SetSelectedComponents(null);

            // 隐藏底层组件/设计器,防止意外的指向他们,在他们销毁之后
            IDesigner rootDesignerHolder = rootDesigner;
            IComponent rootComponentHolder = rootComponent;

            rootDesigner = null;
            rootComponent = null;
            rootComponentClassName = null;

            SedionDesignSite[] siteArray = new SedionDesignSite[sites.Values.Count];
            sites.Values.CopyTo(siteArray, 0);

            // 删除所有设计器,底层设计器最后销毁
            IDesigner[] designers = new IDesigner[designerTable.Values.Count];
            designerTable.Values.CopyTo(designers, 0);
            designerTable.Clear();

            loadingDesigner = true;
            DesignerTransaction trans = CreateTransaction();

            try
            {
                for (int i = 0; i < designers.Length; i++)
                {
                    if (designers[i] != rootDesignerHolder)
                    {
                        try
                        {
                            // 销毁设计器
                            designers[i].Dispose();
                        }
                        catch
                        {
                            Debug.Fail(String.Concat("Designer ", designers[i].GetType().Name, " threw an exception during Dispose."));
                        }
                    }
                }

                // 销毁所有组件
                for (int i = 0; i < siteArray.Length; i++)
                {
                    SedionDesignSite site = siteArray[i];
                    IComponent comp = site.Component;

                    if (comp != null && comp != rootComponentHolder)
                    {
                        try
                        {
                            comp.Dispose();
                        }
                        catch
                        {
                            Debug.Fail(String.Concat("Component ", site.Name, " threw during dispose. Bad component!"));
                        }

                        if (comp.Site != null)
                        {
                            Debug.Fail(String.Concat("Component ", site.Name, " did not remove itself from its containers"));
                            Remove(comp);
                        }
                    }
                }

                // 最后销毁底层设计器/组件
                if (rootComponentHolder != null)
                {
                    try
                    {
                        rootComponentHolder.Dispose();
                    }
                    catch
                    {
                        Debug.Fail(String.Concat("Component ", rootComponentHolder.GetType().Name, " threw during dispose. Bad component!!"));
                    }

                    if (rootComponentHolder.Site != null)
                    {
                        Debug.Fail(String.Concat("Component ", rootComponentHolder.Site.Name, " did not remove itself from its container"));
                        Remove(rootComponentHolder);
                    }
                }

                sites.Clear();
                if (components != null)
                    components.Clear();
            }
            finally
            {
                loadingDesigner = false;
                trans.Commit();
            }

            // 清除视图窗体
            if (documentWindow != null)
                documentWindow.SetDesigner(null);
        }

        /// <summary>
        ///  用designerLoader 导入document
        /// </summary>
        private void Load(Boolean reloading)
        {
            Cursor oldCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            this.reloading = reloading;

            try
            {
                if (!reloading && designerLoader is IExtenderProvider)
                    ((IExtenderProviderService)this).AddExtenderProvider((IExtenderProvider)designerLoader);

                loadingDesigner = true;
                loadError = null;
                designerLoader.BeginLoad(this);
            }
            catch (Exception e)
            {
                // 出错了记录错误
                Exception newEx = e;
                if (e is TargetInvocationException)
                    newEx = e.InnerException;

                String message = newEx.Message;

                if (message == null || message.Length == 0)
                {
                    Debug.Fail("Parser has throw an exception that has no friendly message", newEx.ToString());
                    newEx = new Exception(String.Concat("Parser has throw exception that has no friendly message ", newEx.ToString()));
                }

                ArrayList errorList = new ArrayList();
                errorList.Add(newEx);
                ((IDesignerLoaderHost)this).EndLoad(null, false, errorList);
            }
            Cursor.Current = oldCursor;
        }

        #region IDesignerLoaderHost 成员

        /// <summary>
        ///  当导入结束时被designer loader调用
        /// </summary>
        public void EndLoad(string baseClassName, bool successful, ICollection errorCollection)
        {
            Boolean wasReload = reloading;
            Boolean wasLoading = loadingDesigner;

            // 重置变量
            this.loadingDesigner = false;
            this.reloading = false;

            if (baseClassName != null)
                this.rootComponentClassName = baseClassName;

            // 出错了,那么报告他们
            if (successful && rootComponent == null)
            {
                ArrayList errorList = new ArrayList();
                errorList.Add(new Exception("No Base Class"));
                errorCollection = errorList;
                successful = false;
            }

            if (!successful)
            {
                // document只加载了一部分,卸载它们
                // 并记录错误
                try
                {
                    UnloadDocument();
                }
                catch (Exception ex)
                {
                    Debug.Fail("Failed to unload after a... failed load.", ex.ToString());
                }

                if (errorCollection != null)
                {
                    foreach (Object errorObj in errorCollection)
                    {
                        if (errorObj is Exception)
                            loadError = (Exception)errorObj;
                        loadError = new Exception(errorObj.ToString());
                        break;
                    }
                }
                else
                {
                    loadError = new Exception("Unknown Load Error");
                }

                // 设置底层视图为null
                documentWindow.SetDesigner(null);
            }
            else
            {
                // 防止已经加载过了又调用EndLoading方法
                if (wasLoading)
                {
                    if (LoadComplete != null)
                        LoadComplete(this, EventArgs.Empty);
                }
            }

            documentWindow.ReportErrors(errorCollection);
            documentWindow.Visibility = true;
        }

        public void Reload()
        {
            if (designerLoader == null || documentWindow == null)
                return;

            // 在重新加载之前先清理缓存
            designerLoader.Flush();

            Cursor oldCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;

            ICollection selectObjects = null;
            ArrayList selectedNames = null;

            IServiceProvider provider = (IServiceProvider)this;
            ISelectionService selectionService = (ISelectionService)provider.GetService(typeof(ISelectionService));

            if (selectionService != null)
            {
                selectObjects = selectionService.GetSelectedComponents();
                selectedNames = new ArrayList();

                foreach (Object comp in selectObjects)
                {
                    if (comp is IComponent && ((IComponent)comp).Site != null)
                        selectedNames.Add(((IComponent)comp).Site.Name);
                }
            }

            try
            {
                UnloadDocument();
                Load(true);
            }
            finally
            {
                if (selectionService != null)
                {
                    ArrayList selection = new ArrayList();
                    foreach (String name in selectedNames)
                    {
                        if (name != null)
                        {
                            IComponent comp = ((IContainer)this).Components[name];
                            if (comp != null)
                                selection.Add(comp);
                        }
                    }

                    selectionService.SetSelectedComponents(selection);
                }

                Cursor.Current = oldCursor;
            }
        }

        #endregion
    }

    /// <summary>
    ///  实现添加,更改,重命名组件的事件添加和移除处理程序
    /// </summary>
    public partial class SedionDesignerHost : IComponentChangeService
    {

        #region IComponentChangeService 成员

        public event ComponentChangedEventHandler ComponentChanged;

        public event ComponentChangingEventHandler ComponentChanging;

        public event ComponentEventHandler ComponentAdded;
        private void OnComponentAdded(ComponentEventArgs ce)
        {
            if (ComponentAdded != null)
            {
                ITypeResolutionService trs = ((IServiceContainer)this).GetService(typeof(ITypeResolutionService)) as ITypeResolutionService;
                trs.ReferenceAssembly(ce.Component.GetType().Assembly.GetName());

                ComponentAdded(this, ce);
            }
        }

        public event ComponentEventHandler ComponentAdding;
        private void OnComponentAdding(ComponentEventArgs ce)
        {
            if (ComponentAdding != null)
                ComponentAdding(this, ce);
        }

        public event ComponentRenameEventHandler ComponentRename;
        internal void OnComponentRename(ComponentRenameEventArgs cre)
        {
            if (ComponentRename != null)
                ComponentRename(this, cre);
        }

        public event ComponentEventHandler ComponentRemoved;
        private void OnComponentRemoved(ComponentEventArgs ce)
        {
            if (ComponentRemoved != null)
                ComponentRemoved(this, ce);
        }

        public event ComponentEventHandler ComponentRemoving;
        private void OnComponentRemoving(ComponentEventArgs ce)
        {
            if (ComponentRemoving != null)
                ComponentRemoving(this, ce);
        }

        /// <summary>
        ///  在属性被更改时调用
        /// </summary>
        public void OnComponentChanged(object component, MemberDescriptor member, object oldValue, object newValue)
        {
            // 如果还在加载,那么无视change
            if (Loading) return;

            if (ComponentChanged != null)
            {
                ComponentChangedEventArgs cce = new ComponentChangedEventArgs(component, member, oldValue, newValue);
                ComponentChanged(this, cce);
            }
        }

        /// <summary>
        ///  当属性要改变时调用
        /// </summary>
        public void OnComponentChanging(object component, MemberDescriptor member)
        {
            if (Loading)
            {
                if (member.Name == "Size")
                {
                    string _DEBUG_ = member.Name;
                }
                return;
            }

            if (ComponentChanging != null)
            {
                ComponentChangingEventArgs ce = new ComponentChangingEventArgs(component, member);
                ComponentChanging(this, ce);
            }
        }

        #endregion
    }

    /// <summary>
    ///  实现添加或移除扩展程序
    /// </summary>
    public partial class SedionDesignerHost : IExtenderProviderService
    {
        // 在当前窗体上的扩展
        private ArrayList extenderProviders;

        #region IExtenderProviderService 成员

        void IExtenderProviderService.AddExtenderProvider(IExtenderProvider provider)
        {
            if (extenderProviders == null)
                extenderProviders = new ArrayList();
            extenderProviders.Add(provider);
        }

        void IExtenderProviderService.RemoveExtenderProvider(IExtenderProvider provider)
        {
            if (extenderProviders != null)
                extenderProviders.Remove(provider);
        }

        #endregion
    }

    /// <summary>
    ///  实现在添加和移除根设计器.选定的组件已更改.当前的根设计器已更改是提供事件通知
    /// </summary>
    public partial class SedionDesignerHost : IDesignerEventService
    {
        #region IDesignerEventService 成员

        public IDesignerHost ActiveDesigner
        {
            get { return this; }
        }

        public event ActiveDesignerEventHandler ActiveDesignerChanged;

        public event DesignerEventHandler DesignerCreated;

        public event DesignerEventHandler DesignerDisposed;

        public DesignerCollection Designers
        {
            get { return new DesignerCollection(new IDesignerHost[] { this }); }
        }

        public event EventHandler SelectionChanged;

        #endregion
    }
}
